package com.sky.interceptor;

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    // 1.切点
    @Pointcut("@annotation(com.sky.annotation.AutoFill)")
    public void pt() {
    }

    // 2.通知方法
    @Before("pt()")
    public void autoFill(JoinPoint joinPoint) {
        // 1.需要动态获取方法上的注解,并且获取注解中的属性
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // (MethodSignature)获取真正的方法

        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        // 获取真正方法上的注解,看有没有这个注解AutoFill.class

        OperationType operationType = autoFill.value(); // 获取它的值

        try {
            // 2.动态获取入参(已经知道只有一个参数,其中包含需要映射的内容)
            Object arg = joinPoint.getArgs()[0];
            // 3.判断是更新还是新增
            if (OperationType.INSERT == operationType) {
                // 4.用反射获取对象的方法,然后进行动态赋值
                Method setCreatTime = arg.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
                Method setUpdateTime = arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                Method setCreatUser = arg.getClass().getDeclaredMethod("setCreateUser", Long.class);
                Method setUpdateUser = arg.getClass().getDeclaredMethod("setUpdateUser", Long.class);

                setCreatTime.invoke(arg, LocalDateTime.now());
                setUpdateTime.invoke(arg, LocalDateTime.now());
                setCreatUser.invoke(arg, BaseContext.getCurrentId());
                setUpdateUser.invoke(arg, BaseContext.getCurrentId());
            }


            if (OperationType.UPDATE == operationType) {
                Method setUpdateTime = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

                setUpdateTime.invoke(arg, LocalDateTime.now());
                setUpdateUser.invoke(arg, BaseContext.getCurrentId());
            }
        } catch (Exception e) {
            log.info("动态注入属性失败!");
        }
    }
}